#pragma once
/* 
* COPYRIGHT 2012 Mafahir Fairoze
* 
* This file is part of Vector Template Library (Vtl) v1.0.
* (Project Website : http://mafahir.wordpress.com/projects/neuralplusplus)
* 
* Vector Template Library (Vtl) v1.0 is a free software. You can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
* 
* Vector Template Library (Vtl) v1.0 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License <http://www.gnu.org/licenses/> for more details.
*/

#include "Vtl/eigen.h"
#include "Vtl/Polygon.h"

namespace Vtl
{
	namespace intersections
	{
		/*!
		*  \brief Intersects two lines(Rays).
		*  \param[in] _LineA 
		*  \param[in] _LineB 
		*  \param[out] _Point (optional) the intersection point of line Defaults to NULL.
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if the two lines intersect each other.
		*/
		template <typename Scalar, int Dimension>
		inline bool lineWithLineIntersection(const Eigen::ParametrizedLine<Scalar, Dimension> &_LineA,
			const Eigen::ParametrizedLine<Scalar, Dimension> &_LineB, 
			Eigen::Matrix<Scalar, Dimension, 1> *_Point = NULL,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Returns the shortest line segment between two lines(Rays).
		*  \param[in] _LineA 
		*  \param[in] _LineB 
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return Eigen::ParametrizedLine<Scalar, Dimension> the direction maginitude of the returned line is the length of the shortest line segment.
		*/
		template <typename Scalar, int Dimension>
		inline Eigen::ParametrizedLine<Scalar, Dimension> lineToLineSegment(const Eigen::ParametrizedLine<Scalar, Dimension> &_LineA,
			const Eigen::ParametrizedLine<Scalar, Dimension> &_LineB,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Intersects a line with a polygon face.
		*  \param[in] _Line 
		*  \param[in] _Face polygonal face. All points in the polygon must be in the same hyperplane.
		*  \param[out] _Point (optional) the intersection point. Defaults to NULL.
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if it does intersect.
		*/
		template <typename Scalar, int Dimension>
		inline bool lineWithFaceIntersection(const Eigen::ParametrizedLine<Scalar, Dimension> &_Line,
			const Polygon<Scalar, Dimension> &_Face,
			Eigen::Matrix<Scalar, Dimension, 1> *_Point = NULL,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Intersects a line with polygon in [i,j] plane.
		*  \param[in] _Line n-dimensional line to intersect.
		*  \param[in] _2DPolygon 2-dimensional polygon.
		*  \param[out] _Points (optional) the array of intersection points. Defaults to NULL.
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if it does intersect.
		*/
		template <typename Scalar, int Dimension>
		inline bool lineWith2DPolygonIntersection(const Eigen::ParametrizedLine<Scalar, Dimension> &_Line,
			const Polygon<Scalar, 2> &_2DPolygon,
			std::vector<Eigen::Matrix<Scalar, 2, 1>, Eigen::aligned_allocator<Eigen::Matrix<Scalar, 2, 1>>> *_Points = NULL,
			const double &_Eps = 1e-4);

		/*!
		*  \brief Intersects a line with an excluded polygon.
		*  \param[in] _Line n-dimensional line to intersect.
		*  \param[in] _2DPolygon 2-dimensional polygon.
		*  \param[in] _PolygonBaseLineHeight excluded polygon minimum height.
		*  \param[in] _PolygonHeight excluded polygon height from the base line height.
		*  \param[out] _Point (optional) the nearest intersection point. Defaults to NULL.
		*  \param[in] _Eps (optional) Epsilon, increased value will result reduced accuracy of computation. Defaults to 1e-4.
		*  \return bool returns TRUE if it does intersect.
		*/
		template <typename Scalar, int Dimension>
		inline bool lineWithExcludedPolygonIntersection(const Eigen::ParametrizedLine<Scalar, Dimension> &_Line,
			const Polygon<Scalar, 2> &_2DPolygon,
			const Scalar &_PolygonBaseLineHeight,
			const Scalar &_PolygonHeight,
			Eigen::Matrix<Scalar, Dimension, 1> *_Point = NULL,
			const double &_Eps = 1e-4);
	};
};

#include "Vtl/impl/intersections.hpp"